#ifndef ENTITY_H
#define ENTITY_H

#include "Sprite.h"
#include "Physics.h"
#include "Maths.h"
#include "String.h"

//CWorld
    //std::vector<CCollider*> m_pColliders;
    
//Circle colliders, mask colliders

//CCollider
//{
//    
//    
//
//}
    

//Forward declaration
class CConstraint;

class CEntity
{
    
private:
    
    friend class CWorld;
    
    CEntity(String sName, Vector vPos, String sTextureName, RGBAColor rgbaColor = RGBAColor(1.f, 1.f, 1.f, 1.f));
    
    void init(String sName, Vector vPos, String sTextureName, RGBAColor rgbaColor = RGBAColor(1.f, 1.f, 1.f, 1.f));
    void cleanup();
public:
    void update(Scalar fTimeStep);
    void draw();
    
    //TODO: Add properties
    //      collides with level
    //      collides with other entities
    //      is solid
    
    //static int countCollidingPixels(CEntity& ent1, CEntity& ent2, int iXOffset = 0, int iYOffset = 0);
    static void collideEntities(CEntity* ent1, CEntity* ent2);
    
    Vector& getPos()                 { return m_pPhysics->getPos(); }
    Scalar& getAngle()               { return m_pPhysics->getAngle(); }
    long getWidth()                 { return m_pSprite->getWidth(); }
    long getHeight()                { return m_pSprite->getHeight(); }
    Scalar getCollisionRadius()     { return m_fCollisionRadius; }
    bool isSolid()                  { return m_pPhysics->isSolid(); }
    
    Vector getFacing()
    {
        
        //Check if we have calculated the facing direction already this frame
        if (m_vFacing.isZero())
            m_vFacing = Vector(cos(getAngle() + PI/2.f), sin(getAngle() + PI/2.f));
        return m_vFacing;
        
    }
    
    void applyForce(Vector vForce) { m_pPhysics->applyForce(vForce); }
    //Pass force and absolute location of application
    void applyForce(Vector vForce, Vector vPos) { m_pPhysics->applyForce(vForce, vPos); }
    
    CSprite*        getSprite()     { return m_pSprite; }
    CPhysicsPoint*   getPhysics()    { return m_pPhysics; }
    
    void setIsOnGround(bool bVal)       { m_bIsOnGround = bVal; }
    
    //TODO: Replace with segment structure or just two CPoints
    void alignWith(CSegment pSegment);
    
protected:
    
    //Components
    CPhysicsPoint*  m_pPhysics;
    CSprite*        m_pSprite;
    
    //Properties
    Scalar m_fCollisionRadius;
    String m_sName;
    bool m_bIsOnGround;
    //TODO: Check if this is still needed
    Vector m_vFacing;
    
    CSegment m_pAlignedWith;
    
};

#endif //ENTITY_H
